package com.maktoub.project.controller;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.maktoub.apiclientstart.client.ApiInterfaceClient;
import com.maktoub.common.model.entity.InterfaceInfo;
import com.maktoub.common.model.entity.User;
import com.maktoub.project.common.BaseResponse;
import com.maktoub.project.common.ErrorCode;
import com.maktoub.project.common.ResultUtils;
import com.maktoub.project.exception.BusinessException;
import com.maktoub.project.model.dto.interfacecollectinfo.InterfaceCollectInfoAddRequest;
import com.maktoub.project.model.dto.interfacecollectinfo.InterfaceCollectInfoQueryRequest;
import com.maktoub.project.model.dto.interfacecollectinfo.InterfaceCollectInfoUpdateRequest;
import com.maktoub.project.model.dto.interfaceinfo.InterfaceInfoQueryRequest;
import com.maktoub.project.model.entity.InterfaceCollectInfo;
import com.maktoub.project.model.vo.InterfaceAndCollectVO;
import com.maktoub.project.service.InterfaceCollectInfoService;
import com.maktoub.project.service.InterfaceInfoService;
import com.maktoub.project.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 帖子接口
 *
 * @author yupi
 */
@RestController
@RequestMapping("/interfaceCollectInfo")
@Slf4j
public class InterfaceCollectInfoController {

    @Resource
    private InterfaceCollectInfoService interfaceCollectInfoService;

    @Autowired
    ApiInterfaceClient apiInterfaceClient;

    @Autowired
    InterfaceInfoService interfaceInfoService;
    //    ApiInterfaceClient tempapiInterfaceClient1;
    @Resource
    private UserService userService;


    // region 增删改查

    /**
     * 创建
     *
     * @param interfaceCollectInfoAddRequest
     * @param request
     * @return
     */
    @PostMapping("/add")
    public BaseResponse<Long> addInterfaceCollectInfo(@RequestBody InterfaceCollectInfoAddRequest interfaceCollectInfoAddRequest,
                                                      HttpServletRequest request) {
        if (interfaceCollectInfoAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        InterfaceCollectInfo interfaceCollectInfo = new InterfaceCollectInfo();
        BeanUtils.copyProperties(interfaceCollectInfoAddRequest, interfaceCollectInfo);
        User loginUser = userService.getLoginUser(request);
        Long id = loginUser.getId();
        interfaceCollectInfo.setUserId(id);
        // 校验,添加，与其他校验传入得参数就是一个add不一样
        interfaceCollectInfoService.validInterfaceCollectInfo(interfaceCollectInfo, true);

        LambdaQueryWrapper<InterfaceCollectInfo> eq = new LambdaQueryWrapper<InterfaceCollectInfo>().eq(InterfaceCollectInfo::getUserId, id)
                .eq(InterfaceCollectInfo::getInterfaceId, interfaceCollectInfoAddRequest.getInterfaceId());
        InterfaceCollectInfo one = interfaceCollectInfoService.getOne(eq);
        if (one != null) {
            throw new BusinessException(401, "您已收藏过该接口");
        }

        boolean result = interfaceCollectInfoService.save(interfaceCollectInfo);
        if (!result) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        long newInterfaceCollectInfoId = interfaceCollectInfo.getId();
        return ResultUtils.success(newInterfaceCollectInfoId);
    }

    /**
     * 删除
     *
     * @param interfaceId
     * @param request
     * @return
     */
    @DeleteMapping("/delete")
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse<Boolean> deleteInterfaceCollectInfo(@RequestParam("interfaceId") Long interfaceId,
                                                            HttpServletRequest request) {

        if (interfaceId == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User user = userService.getLoginUser(request);
        Long userId = user.getId();
        int i = 0;
        // 判断是否存在
        LambdaQueryWrapper<InterfaceCollectInfo> eq = new LambdaQueryWrapper<InterfaceCollectInfo>().eq(InterfaceCollectInfo::getUserId, userId)
                .eq(InterfaceCollectInfo::getInterfaceId, interfaceId);
        InterfaceCollectInfo oldInterfaceCollectInfo = interfaceCollectInfoService.getOne(eq);
        if (oldInterfaceCollectInfo == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }

        // 仅本人或管理员可删除
        if (!oldInterfaceCollectInfo.getUserId().equals(user.getId()) && !userService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        oldInterfaceCollectInfo.setUpdateTime(DateTime.now());
        interfaceCollectInfoService.updateById(oldInterfaceCollectInfo);
        boolean b = interfaceCollectInfoService.removeById(oldInterfaceCollectInfo.getId());

        return ResultUtils.success(true);
    }


    /**
     * 更新
     *
     * @param interfaceCollectInfoUpdateRequest
     * @param request
     * @return
     */
    @PostMapping("/update")
    public BaseResponse<Boolean> updateInterfaceCollectInfo(@RequestBody InterfaceCollectInfoUpdateRequest interfaceCollectInfoUpdateRequest,
                                                            HttpServletRequest request) {
        if (interfaceCollectInfoUpdateRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        InterfaceCollectInfo interfaceCollectInfo = new InterfaceCollectInfo();
        BeanUtils.copyProperties(interfaceCollectInfoUpdateRequest, interfaceCollectInfo);

        //为了复用接口方法，所以用InterfaceCollectInfo,也为了用户传不改传的参数
        // 参数校验
        interfaceCollectInfoService.validInterfaceCollectInfo(interfaceCollectInfo, false);
        User user = userService.getLoginUser(request);
        long id = interfaceCollectInfoUpdateRequest.getId();
        // 判断是否存在
        InterfaceCollectInfo oldInterfaceCollectInfo = interfaceCollectInfoService.getById(id);
        if (oldInterfaceCollectInfo == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        // 对应的接口的userId没传进来

        // 仅本人或管理员可修改
        if (!(oldInterfaceCollectInfo.getUserId().equals(user.getId())) && !(userService.isAdmin(request))) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        boolean result = interfaceCollectInfoService.updateById(interfaceCollectInfo);
        return ResultUtils.success(result);
    }

    /**
     * 根据 id 获取
     *
     * @param id
     * @return
     */
    @GetMapping("/get")
    public BaseResponse<InterfaceCollectInfo> getInterfaceCollectInfoById(long id) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        InterfaceCollectInfo interfaceCollectInfo = interfaceCollectInfoService.getById(id);
        return ResultUtils.success(interfaceCollectInfo);
    }

    /**
     * 获取列表（仅管理员可使用）
     *
     * @param interfaceCollectInfoQueryRequest
     * @return
     */
    @GetMapping("/list")
    public BaseResponse<List<InterfaceCollectInfo>> listInterfaceCollectInfo(InterfaceCollectInfoQueryRequest interfaceCollectInfoQueryRequest) {
        InterfaceCollectInfo interfaceCollectInfoQuery = new InterfaceCollectInfo();
        if (interfaceCollectInfoQueryRequest != null) {
            BeanUtils.copyProperties(interfaceCollectInfoQueryRequest, interfaceCollectInfoQuery);
        }
        QueryWrapper<InterfaceCollectInfo> queryWrapper = new QueryWrapper<>(interfaceCollectInfoQuery);
        List<InterfaceCollectInfo> interfaceCollectInfoList = interfaceCollectInfoService.list(queryWrapper);
        return ResultUtils.success(interfaceCollectInfoList);
    }

    /**
     * 分页获取列表
     *
     * @param interfaceInfoQueryRequest
     * @return
     */
    @GetMapping("/list/page")
    public BaseResponse<Page<InterfaceAndCollectVO>> listInterfaceInfoAndCollectByPage(
            InterfaceInfoQueryRequest interfaceInfoQueryRequest,HttpServletRequest request) {
        if (interfaceInfoQueryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        if(loginUser==null){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        Long userId = loginUser.getId();

        long current = interfaceInfoQueryRequest.getCurrent();
        long size = interfaceInfoQueryRequest.getPageSize();


        // description 需支持模糊搜索,为什么需要set NULL,因为后面wrapper传进去如果有值，like就不生效了
//        interfaceInfoQuery.setDescription(null);

        // 限制爬虫
        if (size > 50) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        //描述信息检索
        String description = interfaceInfoQueryRequest.getDescription();
        String name = interfaceInfoQueryRequest.getName();
        String method = interfaceInfoQueryRequest.getMethod();


        System.out.println("description = " + name);
        //and的关系
        LambdaQueryWrapper<InterfaceInfo> queryWrapper = new LambdaQueryWrapper<InterfaceInfo>()
                .like(StringUtils.isNotBlank(description), InterfaceInfo::getDescription, description)
                .like(StringUtils.isNotBlank(name), InterfaceInfo::getName, name)

                .like(StringUtils.isNotBlank(method), InterfaceInfo::getMethod, method);
        //时间
        Page<InterfaceInfo> interfaceInfoPage = interfaceInfoService.page(new Page<>(current, size), queryWrapper);
        List<InterfaceInfo> records = interfaceInfoPage.getRecords();


        //判断ids中，哪些有收藏，userId+interfaceId确定，查找用户所有收藏，再判断哪个interfaceId中哪些在其中，防止反复数据库
        LambdaQueryWrapper<InterfaceCollectInfo> eq = new LambdaQueryWrapper<InterfaceCollectInfo>()
                .eq(InterfaceCollectInfo::getUserId, userId);
        List<InterfaceCollectInfo> collectUser = interfaceCollectInfoService.list(eq);
        Map<Long, List<InterfaceCollectInfo>> collect = collectUser.stream()
                .collect(Collectors.groupingBy(InterfaceCollectInfo::getInterfaceId));
        Set<Long> ids = collect.keySet();
        List<InterfaceAndCollectVO> interfaceAndCollectVOS = new ArrayList<>();
        for (InterfaceInfo item : records) {
            InterfaceAndCollectVO interfaceAndCollectVO = new InterfaceAndCollectVO();
            BeanUtils.copyProperties(item,interfaceAndCollectVO);
            if(ids.contains(item.getId())){
                interfaceAndCollectVO.setCollected(true);
            }
            else{
                interfaceAndCollectVO.setCollected(false);
            }
            interfaceAndCollectVOS.add(interfaceAndCollectVO);
        }

        Page<InterfaceAndCollectVO> interfaceAndCollectVOPage = new Page<>(current, size);
        interfaceAndCollectVOPage.setRecords(interfaceAndCollectVOS);
        interfaceAndCollectVOPage.setTotal(interfaceInfoPage.getTotal());
        System.out.println("interfaceInfoPage = " + interfaceInfoPage);
        return ResultUtils.success(interfaceAndCollectVOPage);
    }


}
